Перейти к основному содержимому

Как правильно писать спецификацию

· 11 мин. чтения

Хождение по воде и разработка по спецификации легки, если и обе заморожены
Эдвард В. Берард

С самого начала моей карьеры, спецификация была больной темой. В маленькой веб-студии написание «спеки» сводилось в лучшем случае к двум-страничкам A4 с описанием нового модуля для уже работающей CMSки. Со временем я повидал и спеки как на 80 страниц от сторонних компаний в фиксированном pdf виде, так и в режиме постоянного scrumа где спека размазана по десяткам задачам в issue tracker'е.

Есть разница между спецификацией (SRS, техническим заданием), документацией и руководству по техническому обслуживанию, она в цели.

Цель спецификации зависит от фазы развития проекта:

  • объяснить всем цель, причины, ограничения, scope и ожидания
  • закрепить требования для этой фазы разработки
  • получить оценку по времени, сложности, доступности ресурсов
  • синхронизировать терминологию, поддерживать единую точку зрения для всех разработчиков
  • под конец реализации, спецификация превращается в документацию — в базу знаний, карту по продукту
  • автоматизировать тесты всех уровней
  • запустить в оборот дальнейшие документы -user guide, release notes, white paper, интерактивную помощь, статьи в блоге
  • подготовить tech manual для ремонта или интеграции системы

Scope — это треугольник ограничивающий ожидания всех сторон и напрямую влияющий на цену и деньги:

  • Функциональность (сумма всех фич)
  • Время выполнения
  • Качество и детальность проработки

Без спецификации и чёткой черты ожиданий функиональности возникнут конфликты. С размытыми ожиданиями заказчик может добавлять в scope всё новые и новые задачи, либо ожидать нереалистично быстрых сроков, либо ожидать другое качество работы по производительности, поддержке устройств или языков.

Работая без спецификации, разработчики постоянно будут сталкиваться с новыми, ранее неизвестными требованиями. Это создаёт угнетающую атмосферу отсутствия прогресса, шаткости всего решения, страха переписывания всего проекта из-за какой-то важной мелочи. Потратив день на продумывание спецификации, можно точней сделать оценку трудозатрат (estimation), сузить конус неопределённости и снизить расходы

Содержание

Спецификация касается только фич, а не задач типа Improvement или Bug. Bug это несоответствие реализации и спеки. Improvement должен включать изменение спецификации на фазе release или code review.

Типы фич

Фичи в свою очередь различаются по глубине и влиянию на продукт. Спецификация для них фокусируется на разных пунктах и средствах донесения информации

  • UI компонент (frontend). Например popup, tooltip, модальное окно, календарь, autocomplete, slider картинок
  • Локальные бизнес-фичи (frontend + backend). Функционал свойственный именно этому продукту и завязанный на поведение пользователя. Например загрузка аватарок, изменение статьи, генерация excel-report'а.
  • Глобальные архитектурные фичи (frontend + backend). Например навигация, переводы, error pages, permissions, email notifications. Завязаны на бизнес-фичи и инфраструктуру.
  • Инфраструктурные, скрытые фичи (backend)​​. Например мониторинг, логи, транзактивность, масштабирование серверов, асинхронные очереди, API reference

Стиль и язык

Спецификацию должен писать один автор, по возможности получая обратную связь от комманды. Это придаст спецификации однородный стиль и единую терминологию.

  • Простота. Используйте минимум иностранных фраз, сленга и аббревиатур. Используйте односложные предложения. 

  • Понятность. Выносите упоминания протоколов, кодировок, расширений в сноски или прячьте эти детали. Приводите пример расчётов

  • Неполнота. Требования не должна досконально описывать всё решение

  • Согласованность. Требования не должны противоречить друг другу

  • Точность и проверяемость. Избегайте:

  • обобщений (every, all, everywhere, never, any, each)

  • бесконечных глаголов (minimize, maximize, optimize, improve)

  • неточных глаголов (support, handle)

  • неточных прилагательных (easy, simple, efficient, flexible, user-friendly, superior, seamless, graceful)

  • неисчислимые (few, several, many, some)

  • «догадайся сам» (etc. и … , including but not limited to, where appropriate, if necessary, adequate, reasonable, sufficient, optionally)

  • латынь — etc., e.g., i.e., ergo

  • Однозначность. 

  • Избегайте двусмысленных выражений (это, который) в сложносочинённых предложениях. Например, что значит "мама / папа "? Правильно — "мама, папа или оба".

  • Одна сущность - один термин, одна операция - один глагол. Минимум обобщений ( "Все варианты", "во всех местах", "Каку продукта Y" )

Версионируйте спецификацию с датами и авторами изменений. Указывайте к какой версии приложения она относится или с какой ветки она актуальна. Лучше всего документацию хранить внутри git вместе с кодом

Joel Spolsky советует разбавлять спеку крупинками юмора, что-бы она не была слишком сухой и трудночитаемой

Уровни обязательности

Некоторые спеки градируют приоритеты языком, указывая какие фичи обязательны а какие не очень:

  • MUST или MUST NOT, REQUIRED, SHALL - строго обязательный функционал
  • SHOULD или SHOULD NOT, RECOMMENDED - желательный функционал, но надо взвесить недостатки
  • MAY, OPTIONAL - реализуется по возможности

Причинно-следственная связь

Описывая пользовательские сценарии, может встать мелкий вопрос - какое время указывать у глаголов? Если указывать везде одно и то же время, неважно - настоящее это, прошедшее или будущее, то разработчик может не отличить последовательность действий. 

Например — «Пользователь достаточным кредитом добавляет продукт в корзину и указывает количество. Зарезервированное количество продуктов на складе увеличивается».

Добавление и указывания количества — это разные операции или одна? А резервация продуктов связана с кредитом, или она для всех типов пользователей происходит?

Необходимо использовать разное время, либо более формально отделять precondition, user action, system reaction и post-condition.

Средства

Я визуал и предпочитаю изображения - UML диаграммы, эскизы (balzamiq, axure), скриншоты со стрелками. Когда дело касается рутинных функций, без текста и списков не обойтись. Таблички полезны когда списки не работают - взаимозависимых данных становится много и они многомерны.

Когда я пытался разобраться в существующих требованиях и существующем проекте, то очень помогал Mind Map, группируя и связывая задачи и требования, создавая точки фокуса. Готовое решение для повторно используемого UI-компонента часто хочется показать разработчикам. Без кода с подсветкой тоже никуда.

Был опыт видеозаписи участка экрана для багов, что-бы показать анимацию и поведение существующего решения. Но для документирования quicktime тоже применим.

Автоматические тесты, да и мануальные формализованные тексты в TestRail, заготовки для UI тестов, наброски BDD — всё это тоже средства документации и проверки решения.

Автогенераторы документации и диаграмм полезны для создания документации по решению — mysql workbench, phpdoc, doxygen, jsduck. Это из разряда холиваров, когда стоит писать тесты - до кода или после него.

Для агрегации всей документации я в основном использовал Confluence, но можно посмотреть на MediaWiki или Google docs. Недостаток их всех в оторванности от кода и git-repo. Хранить документацию вместе с кодом лучше в формате markdown. Редакторы - Mou, Atom, IntelliJ, Marked, Visual Studio Code.

См также:

Наконец, вот шаблон для спеки. Оставьте только стоящие упоминания пункты!

1. Концепция / Обзор

О чём речь?

  • Проблема и цели

  • Stakeholders — заинтересованные пользователи. Кого это касается?

  • Отделы компании — кого затронут изменения, кто что должен будет сделать в процессе

  • Типы пользователей — visitor, user, client, admin

  • Предположения (assumptions) — пользователи, доступность технологий, экономические факторы, развитие конкурентов, вероятное качество данных поставщиков

  • Ограничения (constraints) — независящие от всех обстоятельства по времени, законодательству

  • Scope — что по функционалу войдёт, а что нет

  • Timeline/Lifecycle — что будет происходить после релиза, как будет меняться продукт/этот функционал впоследствии по времени

Скриншот самой важной области

2. Требования

Что мы хотим получить? Общие требования с точки зрения пользователя, не предлагая конкретного решения. Разделив требования от решения подход становится более формализованным и тестируемым.

Цели для каждой из заинтересованных групп.

  • Бизнес-требования. Что необходимо компании? Увеличить прибыль, ускорить рост, снизить риски
  • Пользовательские. Что необходимо конечному пользователю? Ускорение UI, облегчение действий, новые функции.
  • Технические. Что необходимо разработчикам? Поддержка кода, масштабируемость инфраструктуры, определение ошибок.

Из личного опыта, вовремя спросив «зачем бизнесу нужен отдельная от приложения форма авторизации», мы значительно сэкономили время на реализации кросс-доменной авторизации, которая на самом деле бизнесу не нужна была и остались на том же домене, просто с другим дизайном

В больших компаниях, каждое требования выписывается в отдельную БД и получают уникальный ID, на который ссылаются UI-мокапы, код и тесты. Примерно как ticket ID в Jira. Инструменты — SPEQitAccompa

2.1 Нефункциональные требования

Каким мы хотим получить продукт?

Нефункциональные требования при работе продукта

  • Performance - максимальное количество одновременных пользователей, есть ли разница в зависимости от разных операций (read/write/delete), максимальная пропускная способность, время вычисления, время ответа и реакции, загрузка CPU, IO, памяти, max filesize

  • Reliability - как обрабатываются ошибки, перезапуск, дублируются ли данные, failsafe режимы, транзакции

  • Security - разграничение ролей пользователей, какая снижаются риски атак, как хранятся личные данные

  • Usability - ограничения по удобству, минимальное количество кликов при операциях, скорость обновления интерфейса, скорость загрузки страниц, количество элементов в формах или скорость заполнения среднестатистическим пользователем. Есть ли style guide

  • Configurability - где лежат настройки, централизованы ли они, используют ли какой-то сервис

  • Availability - сколько сервис максимально может быть в дауне

  • Durability - сколько надо хранить данные/логи после использования

  • Scalability - есть ли вертикальное/горизонтальное масштабирование сервиса или он фиксирован

Нефункциональные требования при создании

  • Reusability - можно ли повторно использовать, надо ли что-то при этом менять
  • Extensibility - можно ли расширить, добавив новые функции
  • Portability - можно ли запустить на других платформах
  • Interoperability - можно ли компонент использовать согласно открытому стандарту / протоколу
  • Supportability - простота в поддержке. Как легко понять логи, обнаружить ошибку, восстановить данные. Как предсказуемо поведение. Сколько стоит поддержка, какие требования по стилю и качеству кода, техническому долгу
  • Modularity - разделён ли функционал на части и почему. Как при этом происходит сборка и движутся данные
  • Testability - какие типы тестов должны быть и что покрывать, насколько код и архитектура должны быть тестируемыми
  • Localization - надо ли что-то переводить на другой язык, есть ли различие по странам, насколько сложные могут быть фразы, как легко можно добавлять переводы
  • Compatibility - совместимость с разными устройствами и браузерами. Надо ли поддерживать старые версии приложения
  • Legal - ограничения на использование лицензий, влияние на privacy policy, client agreement
  • Accessibility - надо ли поддерживать пользователей с ограничениями зрения. Hotkeys, поддержка разных устройств ввода, SEO-оптимизация

2.2 Функциональные требования

Что мы хотим получить в продукте?

  • Пользовательские сценарии / Use cases​ (краткий обзор, детальней в решении)
  • Для компонентов - размеры, события, анимация, позиционирование, связи с другими элементами (z-index)
  • Business rules - какие ограничения накладывает прикладная область, государственные регуляторы, международные стандарты, контракты

2.3 Риски и сложности

Что надо учитывать, какие взаимосвязи со всем проектом

  • Варьирующиеся и неопределённые внешние требования, сроки и требования по качеству 

  • Внутренние требования (мониторинг, логи, транзакции)

  • Технические зависимости (легаси, тех. долг)

  • Неизвестность инструментов и технологий, предметной области

  • Человеческие зависимости

  • Человеческие отношения - доверие менеджмента комманде, комманды менеджменту (партизанинг), увольнения

  • Структура компании, межкоммандное взаимодействие, субподрядчики, партнёры

  • Внутриполитические дрязги, политика

Нынешнее состояние. Как будет происходить изменение продукта технически и организационно. Кто за что отвечает

Худшие последствия

Как сильно компания чувствительна к провалу этого проекта? 

Какие могут быть репутационные потери, потеря и повреждение данных, юридические обязанности поддерживать решение?

3. Техническое решение

Как это будет сделано? Преимущества и недостатки

Терминология

Единый словарь должен использоваться не только клиентом но и в css, в коде, в базе

Вид статических данных

Терминология плавно перетекает в связи между сущностями:

  1. Entity Relationship диаграмма включает связи сущностей (1:n, n:m). 
  2. Нормальная схема БД. Включает, свойства и их типы, внешние ключи
  3. Class диаграмма — описывают какие классы в коде будут связаны с какими данными. Начинается описание поведения (методов)

Все эти диаграммы говорят о гибкости (насколько сущности разделены), понимаемости (названиях), тестопригодности (инкапсуляции) приложения

Вид пользователя

Пользовательские сценарии (use-case диаграмма) — пошаговое описание функций (роль пользователя, причина, действия, последствия)Альтернативные сценарии (ошибки, валидация ввода). Что должно происходить с частично обработанными данными при ошибках?

Визуальный дизайн

Интерфейс и его взаимодействие с пользователем. Желательно связывать с конкретным use-case

  • Навигация (URL, меню, граф взаимосвязей видов)

  • Эскизы / наброски UI (mockup на доске, бумаге)

  • Визуальный дизайн интерфейса (PSD / HTML) — стиль, анимации, бренд, цвета, шрифты, вдохновение

  • Динамический дизайн / HMTL + JS. Очень полезен для frontend компонентов. Анимация, взаимодействие.

Вид динамических данных

Поток данных (data flow)​ - архитектурный обзор как данные кочуют между сервисами, что от чего зависит
Диаграмма взаимосвязей API

Взаимодействие (collaboration) — какие компоненты кого вызывают по каким методам
Последовательность (sequence) — в каком порядке идёт обмен данными между объектами во времени для конкретной операции
Конечный автомат (state machine) — в каких состояниях данные бывают

Вид сервера

  • Технологии и инструменты для сборки

  • Новые зависимости

  • Библиотеки и фреймворки

  • Репозитории

  • Использование внешних API

  • Отдача своего API вовне

  • Конфигурация

  • Серверы

  • Исключения, коды ошибок

  • Rest API — SwaggerApiary

  • Background-задачи (cron, MQ очереди)

  • Код для повторного использования компонента

  • Какое железо, серверы участвуют, какие компоненты на каких серверах живут

  • Какие шаги по релизу. Миграции БД, сервера. Как происходит откат неудачного релиза, бэкап

См. также:

Specification by Example: How Successful Teams Deliver the Right Software

Gojko Adzic